$KCODE="u"

require 'rubygems'
require 'httpclient'
require 'active_record'
require 'yaml'
require 'logger'
require 'rexml/document'
require 'iconv'
require 'model/Store'
require 'model/Province'
require 'model/City'
require 'model/District'

module DataFetcher
  class Fetcher
    def initialize
      @client = HTTPClient.new

      @apikey = '7f512472d88ab57f863eefe25130d250'

      domain   = 'http://open.k.ai/'
      username = 'withwind2005@yahoo.com.cn'
      password = 'forget'

      @client.set_auth domain, username, password

      dbconfig = YAML::load(File.open('conf/database.yml'))
      ActiveRecord::Base.establish_connection dbconfig
      ActiveRecord::Base.logger = Logger.new('log/info.log')
    end

    def log(message)
      puts message
      ActiveRecord::Base.logger.debug message
    end

    def get_store_list_by_page(page, lon, lat, name)
      store_count = 0;  # 保存的店铺数量

      log "开始获取KAIKAI上#{name}第#{page}页的数据"
      store_url = 'http://open.k.ai/public/poi/search.xml'
      store_parameters = {
        'key' => @apikey,
        'query' => '咖啡',
        'lon' => lon, 'lat' => lat,
        'range' => '100',
        'page' => page
      }
      store_xml = @client.get(store_url, store_parameters).body

      document = REXML::Document.new(store_xml)
      if document.elements['pois/poi_concise'].nil?
        log "#{name}数据获取结束"
        break
      end

      document.elements.each('pois/poi_concise') do |poi|
        reference_id = poi.elements['id'].text
        log "开始处理 id为 #{reference_id} 的店铺数据"
        # 先验证该店铺数据是否已被获取，如果数据已获取，则不再保存
        last_store = Store.find(:first, :conditions=>["reference_id = #{reference_id}"])
        unless last_store.nil?
          next
        end

        # 获取地区信息
        district_id = nil
        district_url = 'http://maps.google.com/maps/api/geocode/xml'
        latlng = poi.elements['lat'].text + ',' + poi.elements['lon'].text
        district_parameters = {'latlng' => latlng, 'sensor' => 'true', 'language' => 'zh-CN'}
        district_xml = @client.get(district_url, district_parameters).body
        district_document = REXML::Document.new(district_xml)
        district_document.elements.each('GeocodeResponse/result/address_component') do |item|
          if item.elements['type'].text.eql?('sublocality')
            long_name = item.elements['long_name'].text
            district = District.find(:first, :conditions=>["name like '%%#{long_name}%%'"])
            unless district.nil?
              district_id = district.id
            end
            break
          end
        end
        # 如果没有获取到地区编号，则不保存数据
        if district_id.nil?
          log "KAIKAI上id为 #{reference_id} 的咖啡馆地区数据 获取失败！"
          next
        end

        Store.transaction do
          begin
            store = Store.new
            store.name = poi.elements['name'].text
            store.address = poi.elements['address'].text
            store.lon = poi.elements['lon'].text
            store.lat = poi.elements['lat'].text
            store.reference_id = poi.elements['id'].text
            store.create_from = 'KAIKAI'
            store.district_id = district_id

            unless store.save
              log "KAIKAI上id为 #{reference_id} 的咖啡馆数据保存失败！"
            else
              log "#{store.name} 数据保存成功！"
              store_count = store_count + 1
            end

          end
        end
      end
      store_count
    end

    def get_store_list(city_id = 1)
      citys = City.find(:all, :conditions =>["id >= '#{city_id}'"], :limit =>10 ,:order =>"id asc")
      for city in citys
        log "开始获取KAIKAI上#{city.id}:#{city.name}的数据"
        page = 0
        while get_store_list_by_page page, city.lon, city.lat, city.name
          page = page + 1
        end
      end
      log "数据获取结束"
    end

    def get_location_latlon(location)
      location_url = 'http://maps.google.com/maps/api/geocode/xml'
      location_parameters = {'address' => location.name, 'sensor' => 'true', 'language' => 'zh-CN'}
      location_xml = @client.get(location_url, location_parameters).body
      puts location.name
      #      puts location_xml
      location_document = REXML::Document.new(location_xml)
      if location_document.elements['GeocodeResponse/result/geometry/location/lat'] && location_document.elements['GeocodeResponse/result/geometry/location/lng']
        location.lat = location_document.elements['GeocodeResponse/result/geometry/location/lat'].text
        location.lon = location_document.elements['GeocodeResponse/result/geometry/location/lng'].text
      end
      location
    end

    def get_district_latlon
      District.find(:all, :conditions=>["lat is null or lon is null"]).each() do |d|
        District.transaction do
          get_location_latlon d
          d.save
        end
      end
    end

    def get_province_latlon
      Province.find(:all, :conditions=>["lat is null or lon is null"]).each() do |p|
        Province.transaction do
          get_location_latlon p
          p.save
        end
      end
    end

    def get_city_latlon
      City.find(:all, :conditions=>["lat is null or lon is null"]).each() do |c|
        City.transaction do
          get_location_latlon c
          c.save
        end
      end
    end

  end

  fetcher = Fetcher.new
  fetcher.get_store_list 1
  #  fetcher.get_district_latlon
  #  fetcher.get_province_latlon
  #  fetcher.get_city_latlon

end
